package com.md.api.controller;

import com.md.api.common.utils.*;
import com.md.api.dao.PhotoInfoMapper;
import com.md.api.dao.TbOrderVirtuallyMapper;
import com.md.api.dao.UserMapper;
import com.md.api.entity.*;
import com.md.api.service.PhotoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.*;
import java.util.regex.Pattern;

/**
 * @Author liujie
 * @ClassName uploadController
 * @Date 2022年11月01日14:01
 **/

@Slf4j
@RequestMapping("/file")
@RestController
public class UploadController {
    @Resource
    TokenUtil tokenUtil;
    @Resource
    TbOrderVirtuallyMapper storageMapper;
    @Resource
    UserMapper userMapper;
    @Autowired
    FileProperties properties;
    @Value("${downUrl}")
    public String downUrl;
    @Value("${fileName}")
    public String fileName;
    @Resource
    PhotoInfoMapper photoMapper;
    @Resource
    PhotoService photoService;

    @PostMapping("/headUpload")
    @ResponseBody
    public HttpResult headUpload(HttpServletRequest request,MultipartFile file) {
        try {
            String language = request.getHeader("language");
            FileTool.checkSize(properties.getMaxSize(), file.getSize());
            String originalFilename = file.getOriginalFilename();
            String fileName = originalFilename.substring(0, originalFilename.lastIndexOf("."));
            Pattern p = Pattern.compile("[`!@$^&*=|{}':;',\\\\[\\\\].<>/?！@￥……&*——|{}【】‘；：”“'。，、？]");
            if(p.matcher(fileName).find()) {
                if(StringUtils.isNotEmpty(language)&&language.equals("en")){
                    return HttpResult.fail("The file name cannot contain special symbols");
                }
                return HttpResult.fail("文件名不能含有特殊符号！");
            }
            String suffix = FileTool.getExtensionName(originalFilename);
            String type = FileTool.getFileType(suffix.toLowerCase());
            if (StringUtils.isEmpty(type)){
                if(StringUtils.isNotEmpty(language)&&language.equals("en")){
                    return HttpResult.fail("Please upload the correct format file");
                }
                return HttpResult.fail("请上传正确格式文件！");
            }

//            String fileName = UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();
            String path = AliOssUtil.upload(file, AliOssUtil.SYS,fileName+"."+suffix);

//            long fileSize = AliOssUtil.getFileSize(path);
//            System.out.println(path+":fileSize:"+fileSize);
//            long folderSize = AliOssUtil.getFolderSize(userPath);
//            System.out.println(userPath+":folderSize:"+folderSize);
            return new HttpResult(URLDecoder.decode(path,"UTF-8"));
        } catch (Exception e) {
            log.error("上传失败", e);
            return HttpResult.fail(e.getMessage());
        }
    }


    /**
     * 文件上传请求
     */
    @PostMapping("/customUpload")
    @ResponseBody
    public HttpResult customUpload(HttpServletRequest request,MultipartFile file) {
        try {
            System.out.println("file.getBytes():"+file.getSize());
            String language = request.getHeader("language");
            String userPath = tokenUtil.getUserId(request);
            UserInfo user = userMapper.getByUserId(userPath);
            Double totalEffectiveStorage = storageMapper.getTotalEffectiveStorage(userPath);
            if (null==totalEffectiveStorage) {
                if(StringUtils.isNotEmpty(language)&&language.equals("en")){
                    return HttpResult.fail("Insufficient storage space, please upgrade membership or purchase storage space");
                }
                return HttpResult.fail("存儲空間不足，請升級會員或購買存儲空間！");
            }
            Double total = Double.valueOf(String.valueOf(totalEffectiveStorage*1024*1024*1024));
            log.info("用户已用空间："+user.getUseStorage());
            log.info("用户可用空间："+total);
            if (user.getUseStorage()>=total) {
                if(StringUtils.isNotEmpty(language)&&language.equals("en")){
                    return HttpResult.fail("Insufficient storage space, please upgrade membership or purchase storage space");
                }
                return HttpResult.fail("存儲空間不足，請升級會員或購買存儲空間！");
            }

            FileTool.checkSize(properties.getMaxSize(), file.getSize());
            String originalFilename = file.getOriginalFilename();
            String fileName = originalFilename.substring(0, originalFilename.lastIndexOf("."));
            Pattern p = Pattern.compile("[`!@$^&*=|{}':;',\\\\[\\\\].<>/?！@￥……&*——|{}【】‘；：”“'。，、？]");
            if(p.matcher(fileName).find()) {
                if(StringUtils.isNotEmpty(language)&&language.equals("en")){
                    return HttpResult.fail("The file name cannot contain special symbols");
                }
                return HttpResult.fail("文件名不能含有特殊符号！");
            }
            String suffix = FileTool.getExtensionName(originalFilename);
            String type = FileTool.getFileType(suffix.toLowerCase());
            if (StringUtils.isEmpty(type)){
                if(StringUtils.isNotEmpty(language)&&language.equals("en")){
                    return HttpResult.fail("Please upload the correct format file");
                }
                return HttpResult.fail("请上传正确格式文件！");
            }

//            String fileName = UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();
            String path = AliOssUtil.upload(file, AliOssUtil.CUSTOM+userPath+"/",fileName+"."+suffix);

//            long fileSize = AliOssUtil.getFileSize(path);
//            System.out.println(path+":fileSize:"+fileSize);
//            long folderSize = AliOssUtil.getFolderSize(userPath);
//            System.out.println(userPath+":folderSize:"+folderSize);
            return new HttpResult(URLDecoder.decode(path,"UTF-8"));
        } catch (Exception e) {
            log.error("上传失败", e);
            return HttpResult.fail(e.getMessage());
        }
    }


    @PostMapping("/ftpUpload")
    @ResponseBody
    public HttpResult ftpUpload(HttpServletRequest request, @RequestBody FtpUpload ftpUpload) {
        try {
            if (CollectionUtils.isEmpty(ftpUpload.getPictures())||StringUtils.isEmpty(ftpUpload.getPhotoId())){
                return HttpResult.PARAM_ERROR;
            }
            String language = request.getHeader("language");
            PhotoInfo dbPhoto = photoMapper.getByPhotoId(ftpUpload.getPhotoId());
            if (null!=dbPhoto&&dbPhoto.getStatus()==-1){
                if(StringUtils.isNotEmpty(language)&&language.equals("en")){
                    return HttpResult.fail("The album is frozen. Please renew your membership or contact the administrator to unfreeze it");
                }
                return HttpResult.fail("相冊處於冷凍中，請續費會員或聯係管理員解凍！");
            }
            if (null!=dbPhoto&&dbPhoto.getValidDate().getTime()<new Date().getTime()){
                if(StringUtils.isNotEmpty(language)&&language.equals("en")){
                    return HttpResult.fail("Album activity time has passed, operation not allowed");
                }
                return HttpResult.fail("相冊活動時間已過，不允許操作！");
            }
            if (null!=dbPhoto&&DateUtils.add(new Date(), Calendar.DATE,-30).getTime()>dbPhoto.getCreateTime().getTime()){
                if(StringUtils.isNotEmpty(language)&&language.equals("en")){
                    return HttpResult.fail("No operations allowed after 30 days of album creation");
                }
                return HttpResult.fail("相冊創建30天后不允許操作！");
            }
            String userPath = tokenUtil.getUserId(request);
            UserInfo user = userMapper.getByUserId(userPath);
            Double totalEffectiveStorage = storageMapper.getTotalEffectiveStorage(userPath);
            if (null == totalEffectiveStorage) {
                if (StringUtils.isNotEmpty(language) && language.equals("en")) {
                    return HttpResult.fail("Insufficient storage space, please upgrade membership or purchase storage space");
                }
                return HttpResult.fail("存儲空間不足，請升級會員或購買存儲空間！");
            }
            Double total = Double.valueOf(String.valueOf(totalEffectiveStorage * 1024 * 1024 * 1024));
            if (user.getUseStorage() >= total) {
                if (StringUtils.isNotEmpty(language) && language.equals("en")) {
                    return HttpResult.fail("Insufficient storage space, please upgrade membership or purchase storage space");
                }
                return HttpResult.fail("存儲空間不足，請升級會員或購買存儲空間！");
            }
            PictureInfo pictureInfo = new PictureInfo();
            pictureInfo.setPhotoId(ftpUpload.getPhotoId());
            List<String> paths = new ArrayList<>();
            for (String ftpPath :ftpUpload.getPictures()) {
//                String fileName = UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();
                MultipartFile file = FileUtils.fileUrlConvertToMultipartFile(fileName,ftpPath);
                FileTool.checkSize(properties.getMaxSize(), file.getSize());
                String originalFilename = file.getOriginalFilename();
                String suffix = FileTool.getExtensionName(originalFilename);
                String path = AliOssUtil.upload(file, AliOssUtil.CUSTOM+userPath+"/",originalFilename);
                paths.add(path);
            }
            pictureInfo.setPictureUrl(String.join(",",paths));
            return photoService.savePicture(request,pictureInfo);
        } catch (Exception e) {
            log.error("上传失败", e);
            return HttpResult.fail(e.getMessage());
        }
    }

    //批量上传
    @PostMapping("/customMultipleUpload")
    @ResponseBody
    public HttpResult customMultipleUpload(HttpServletRequest request,MultipartFile[] files) {
        try {
            String language = request.getHeader("language");
            List<String> paths = new ArrayList<>();
            String userPath = tokenUtil.getUserId(request);
            UserInfo user = userMapper.getByUserId(userPath);
            Double totalEffectiveStorage = storageMapper.getTotalEffectiveStorage(userPath);
            if (null==totalEffectiveStorage) {
                if(StringUtils.isNotEmpty(language)&&language.equals("en")){
                    return HttpResult.fail("Insufficient storage space, please upgrade membership or purchase storage space");
                }
                return HttpResult.fail("存儲空間不足，請升級會員或購買存儲空間！");
            }
            Double total = Double.valueOf(String.valueOf(totalEffectiveStorage*1024*1024*1024));
            if (user.getUseStorage()>=total) {
                if(StringUtils.isNotEmpty(language)&&language.equals("en")){
                    return HttpResult.fail("Insufficient storage space, please upgrade membership or purchase storage space");
                }
                return HttpResult.fail("存儲空間不足，請升級會員或購買存儲空間！");
            }
            for (MultipartFile file : files) {
                System.out.println("file.getBytes():"+file.getSize());
                FileTool.checkSize(properties.getMaxSize(), file.getSize());
                String originalFilename = file.getOriginalFilename();
                String substring = originalFilename.substring(0, originalFilename.lastIndexOf("."));
                Pattern p = Pattern.compile("[`!@$^&*=|{}':;',\\\\[\\\\].<>/?！@￥……&*——|{}【】‘；：”“'。，、？]");
                if(p.matcher(substring).find()) {
                    if(StringUtils.isNotEmpty(language)&&language.equals("en")){
                        return HttpResult.fail("The file name cannot contain special symbols");
                    }
                    return HttpResult.fail("文件名不能含有特殊符号！");
                }
                String suffix = FileTool.getExtensionName(originalFilename);
                String type = FileTool.getFileType(suffix.toLowerCase());
                if (StringUtils.isEmpty(type)){
                    if(StringUtils.isNotEmpty(language)&&language.equals("en")){
                        return HttpResult.fail("Please upload the correct format file");
                    }
                    return HttpResult.fail("请上传正确格式文件！");
                }
            }
            for (MultipartFile file : files) {
                String originalFilename = file.getOriginalFilename();
                String suffix = FileTool.getExtensionName(originalFilename);
//                String fileName = UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();
                String path = AliOssUtil.upload(file, AliOssUtil.CUSTOM+userPath+"/",originalFilename);
                paths.add(path);
            }
            return new HttpResult(paths);
        } catch (Exception e) {
            log.error("上传失败", e);
            return HttpResult.fail(e.getMessage());
        }
    }

    @PostMapping("/upload")
    @ResponseBody
    public HttpResult upload(HttpServletRequest request,MultipartFile file) {
        try {

            FileTool.checkSize(properties.getMaxSize(), file.getSize());
            String originalFilename = file.getOriginalFilename();
            String substring = originalFilename.substring(0, originalFilename.lastIndexOf("."));
            Pattern p = Pattern.compile("[`!@$^&*=|{}':;',\\\\[\\\\].<>/?！@￥……&*——|{}【】‘；：”“'。，、？]");
            if(p.matcher(substring).find()) {
                return HttpResult.fail("文件名不能含有特殊符号！");
            }
            String suffix = FileTool.getExtensionName(originalFilename);
            String type = FileTool.getFileType(suffix.toLowerCase());
            if (StringUtils.isEmpty(type)){
                return HttpResult.fail("请上传正确格式文件！");
            }
            String fileName = UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();
            String path = AliOssUtil.upload(file, AliOssUtil.SYS,fileName+"."+suffix);
            return new HttpResult(path);
        } catch (Exception e) {
            log.error("上传失败", e);
            return HttpResult.fail(e.getMessage());
        }
    }

    @PostMapping("/delete")
    @ResponseBody
    public HttpResult upload(HttpServletRequest request,String path) {
        try {
            AliOssUtil.delShopImage(path);
            return HttpResult.OK;
        }catch (Exception e){
            e.printStackTrace();
            return HttpResult.fail("删除失败！");
        }
    }


    /**
     * 附件下载
     *
     * @param request
     * @param response
     */
    @RequestMapping("/downloadTwo")
    public void downloadFileTwo( HttpServletRequest request, HttpServletResponse response) {
        String fileNameParam = request.getParameter(fileName);
        String downUrlParam = request.getParameter(downUrl);
        goToDownload(request, response, downUrlParam, fileNameParam);
    }
    /**
     * 下载
     *
     * @param request
     * @param response
     * @param downUrl  下载的路径
     * @param fjmc     下载文件的名称
     */
    private void goToDownload(HttpServletRequest request, HttpServletResponse response, String downUrl, String fjmc) {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/x-msdownload");
        try {
            String encodenickname = URLEncoder.encode(fjmc,"UTF-8");//转Unicode不然ie会乱码
            response.setHeader("Content-Disposition", "attachment;fileName=" + new String(encodenickname.getBytes("UTF-8"), "ISO8859-1"));
            //这里注掉的代码是本地测试的
//            String path = request.getSession().getServletContext().getRealPath("/");
//            String ATTACH_PATH= AppConfig.getInstance().getProperty("attach.base","");
//            if (StringUtils.isNotEmpty(ATTACH_PATH)) {
//                path = ATTACH_PATH;
//            }
//            logger.debug("=path===" + path);
            File file = new File( downUrl);
            if (!file.exists()) {
                response.sendError(404, "File not found!");
                return;
            }
            long fileLength = file.length();
            response.setHeader("Content-Length", String.valueOf(fileLength));
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
            BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
            byte[] buff = new byte[2048];
            int bytesRead;
            while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
                bos.write(buff, 0, bytesRead);
            }
            bis.close();
            bos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 预览图片&下载文件
     * @param request
     * @param response
     */
    @GetMapping(value = "/static/**")
    public void view(HttpServletRequest request, HttpServletResponse response) {
        InputStream inputStream = null;
        OutputStream outputStream = null;
        try {
            String fileUrl = request.getRequestURI().replace("/file/static", "");
            File file = new File(fileUrl);
            if(!file.exists()){
                response.setStatus(404);
                throw new RuntimeException("文件不存在..");
            }
            response.setContentType("application/force-download");// 设置强制下载不打开
            response.addHeader("Content-Disposition", "attachment;fileName=" + new String(file.getName().getBytes("UTF-8"),"iso-8859-1"));
            inputStream = new BufferedInputStream(new FileInputStream(fileUrl));
            outputStream = response.getOutputStream();
            byte[] buf = new byte[1024];
            int len;
            while ((len = inputStream.read(buf)) > 0) {
                outputStream.write(buf, 0, len);
            }
            response.flushBuffer();
        } catch (IOException e) {
            log.error("预览文件失败" + e.getMessage());
            response.setStatus(404);
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    log.error(e.getMessage(), e);
                }
            }
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    log.error(e.getMessage(), e);
                }
            }
        }
    }



    @GetMapping(value = "/getTemporaryToken")
    public HttpResult getTemporaryToken(HttpServletRequest request) {
//        String userId = tokenUtil.getUserId(request);
        String temporaryToken = AliOssUtil.getTemporaryToken("1357419b32074e3095182088ed480d40");
        if (StringUtils.isEmpty(temporaryToken)){
            return new HttpResult(temporaryToken);
        }
        return HttpResult.fail("token 获取失败！");
    }
}
